package main

import (
	"time"
	"fmt"
	"sync"
	"sync/atomic"
)



func coordinateWithWaitGroup() {
	total := 12
	var num int32
	var wg sync.WaitGroup
	// 定义好goroutine中返回前要执行的defer函数
	deferFunc := func() {
		wg.Done()
	}
	for i := 0; i < total; i++ {
		wg.Add(1)
		go addNum(&num, i, deferFunc)
	}
	wg.Wait()
}

// 这个函数的defer函数通过参数来给出
func addNum(numP *int32, id int, deferFunc func()) {
	defer deferFunc()
	for i := 1; ; i++ {
		currNum := atomic.LoadInt32(numP)
		newNum := currNum + 1
		time.Sleep(time.Millisecond * 200)
		if atomic.CompareAndSwapInt32(numP, currNum, newNum) {
			fmt.Printf("id: %02d 第 %02d 次更新num成功: %d\n", id, i, newNum)
			break
		}
	}
}

func main() {
	coordinateWithWaitGroup()
}